﻿/*
 *
 * The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License"); 
 * you may not use this file except in compliance with the License.
 * 
 * You may obtain a copy of the License at http://www.mozilla.org/MPL/
 * 
 * Software distributed under the License is distributed on an "AS IS" basis, 
 * WITHOUT WARRANTY OF ANY KIND, either express or implied.
 * 
 * See the License for the specific language governing rights and limitations under the License.
*/

using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using System.Web;

namespace FBConnectAuth.Tests
{
	[TestFixture]
	public class FBConnectGraphAPIAuthenticationFixture
	{
		private const string appId = "121091137913619";
		private const string appSecret = "bd1a32c8fe6a105d810d3203f8b0fdbe";
		
		[Test]
		[ExpectedException(typeof(ArgumentException))]
		public void TestConstructor_NullApiKey()
		{
			new FBConnectAuthentication(null, appSecret);
		}

		[Test]
		[ExpectedException(typeof(ArgumentException))]
		public void TestConstructor_NullAppSecret()
		{
			new FBConnectAuthentication(appId, null);
		}

		[Test]
		[ExpectedException(typeof(ArgumentException))]
		public void TestConstructor_EmptyApiKey()
		{
			new FBConnectAuthentication("", appSecret);
		}

		[Test]
		[ExpectedException(typeof(ArgumentException))]
		public void TestConstructor_EmptyAppSecret()
		{
			new FBConnectAuthentication(appId, "");
		}

		[Test]
		public void TestConstructor_ValidParams()
		{
			new FBConnectAuthentication(appId, appSecret);
		}

		[Test]
		[ExpectedException(typeof(ArgumentNullException))]
		public void TestValidate_NullCookies()
		{
			var auth = new FBConnectAuthentication(appId, appSecret);
			auth.Validate(null);
		}

		//

		[Test]
		public void TestValidate_ValidSignature()
		{
			//"access_token=121091137913619|2.a04r8V6C0WQE1CGkVuxNTw__.3600.1273809600-1834825588|cMdI_lQNBYXLKpw76wjARD9y9sM.&expires=1273809600&secret=yuz1uMckuB8QwNNY2plU7A__&session_key=2.a04r8V6C0WQE1CGkVuxNTw__.3600.1273809600-1834825588&sig=91b7cb83ebeef852b1bdda7bfcc3e129&uid=1834825588"
			FBConnectAuthentication auth = new FBConnectAuthentication(appId,appSecret);
			var cookies = new HttpCookieCollection {
			       		new HttpCookie("fbs_121091137913619", "\"access_token=121091137913619|2.a04r8V6C0WQE1CGkVuxNTw__.3600.1273809600-1834825588|cMdI_lQNBYXLKpw76wjARD9y9sM.&expires=1273809600&secret=yuz1uMckuB8QwNNY2plU7A__&session_key=2.a04r8V6C0WQE1CGkVuxNTw__.3600.1273809600-1834825588&sig=91b7cb83ebeef852b1bdda7bfcc3e129&uid=1834825588\"")
			};
			
			ValidationState expected = ValidationState.Valid;
			ValidationState actual = auth.Validate(cookies);

			Assert.AreEqual(expected,actual,"Signature was expected to be valid.");

		}

		[Test]
		public void TestValidate_InvalidSignature()
		{
			FBConnectAuthentication auth = new FBConnectAuthentication(appId, appSecret);
			var cookies = new HttpCookieCollection {
			       		new HttpCookie("fbs_121091137913619", "\"access_token=121091137913619|2.a04r8V6C0WQE1CGkVuxNTw__.3600.1273809600-1834825588|cMdI_lQNBYXLKpw76wjARD9y9sM.&expires=1273809600&secret=yuz1uMckuB8QwNNY2plU7A__&session_key=2.a04r8V6C0WQE1CGkVuxNTw__.3600.1273809600-1834825588&sig=91b7cb83345345edgfgbfcc3e129&uid=1834825588\"")
			};

			ValidationState expected = ValidationState.InvalidSignature;
			ValidationState actual = auth.Validate(cookies);

			Assert.AreEqual(expected, actual, "Signature was expected to be invalid.");

		}
		
		[Test]
		public void TestValidate_MissingSignature_ButOtherFBInfoIsThere()
		{
			FBConnectAuthentication auth = new FBConnectAuthentication(appId, appSecret);
			var cookies = new HttpCookieCollection {
			       		new HttpCookie("fbs_121091137913619", "\"access_token=121091137913619|2.a04r8V6C0WQE1CGkVuxNTw__.3600.1273809600-1834825588|cMdI_lQNBYXLKpw76wjARD9y9sM.&expires=1273809600&secret=yuz1uMckuB8QwNNY2plU7A__&session_key=2.a04r8V6C0WQE1CGkVuxNTw__.3600.1273809600-1834825588&uid=1834825588\"")
			};

			ValidationState expected = ValidationState.NoSignatureFound;
			ValidationState actual = auth.Validate(cookies);

			Assert.AreEqual(expected, actual, "Signature was not included in cookie collection.");
		}

		[Test]
		public void TestValidate_MissingSignature()
		{
			HttpCookieCollection cookies = CreateCookiesWithNoFBConnectInfo();

			FBConnectAuthentication auth = new FBConnectAuthentication(appId, appSecret);
			ValidationState expected = ValidationState.NoSignatureFound;
			ValidationState actual = auth.Validate(cookies);

			Assert.AreEqual(expected, actual, "Signature was not included in cookie collection.");
		}


		[Test]
		[ExpectedException(typeof(ArgumentNullException))]
		public void TestGetSession_NullCookies()
		{
			FBConnectAuthentication auth = new FBConnectAuthentication(appId, appSecret);
			auth.GetSession(null);
		}

		[Test]
		public void TestGetSession_ValidSignature()
		{
			//"access_token=121091137913619|2.a04r8V6C0WQE1CGkVuxNTw__.3600.1273809600-1834825588|cMdI_lQNBYXLKpw76wjARD9y9sM.&expires=1273809600&secret=yuz1uMckuB8QwNNY2plU7A__&session_key=2.a04r8V6C0WQE1CGkVuxNTw__.3600.1273809600-1834825588&sig=91b7cb83ebeef852b1bdda7bfcc3e129&uid=1834825588"
			FBConnectAuthentication auth = new FBConnectAuthentication(appId,appSecret);
			var cookies = new HttpCookieCollection {
			       		new HttpCookie("fbs_121091137913619", "\"access_token=121091137913619|2.a04r8V6C0WQE1CGkVuxNTw__.3600.1273809600-1834825588|cMdI_lQNBYXLKpw76wjARD9y9sM.&expires=1273809600&secret=yuz1uMckuB8QwNNY2plU7A__&session_key=2.a04r8V6C0WQE1CGkVuxNTw__.3600.1273809600-1834825588&sig=91b7cb83ebeef852b1bdda7bfcc3e129&uid=1834825588\"")
			};

			string userId = "1834825588";
			string sessionSecret = "yuz1uMckuB8QwNNY2plU7A__";
			string sessionKey = "2.a04r8V6C0WQE1CGkVuxNTw__.3600.1273809600-1834825588";
			string accessToken = "121091137913619|2.a04r8V6C0WQE1CGkVuxNTw__.3600.1273809600-1834825588|cMdI_lQNBYXLKpw76wjARD9y9sM.";
			int expires = 1273809600;

			FBConnectSession session = auth.GetSession(cookies);
			
			Assert.IsNotNull(session,"Session was not expected to be null.");
			Assert.AreEqual(userId,session.UserID);
			Assert.AreEqual(sessionSecret, session.SessionSecret);
			Assert.AreEqual(sessionKey, session.SessionKey);
			Assert.AreEqual(expires, session.Expires);
			Assert.AreEqual(accessToken, session.AccessToken);
		}
		
		[Test]
		public void TestGetSession_InvalidSignature()
		{
			bool correctExceptionThrown = false;
			
			FBConnectAuthentication auth = new FBConnectAuthentication(appId,appSecret);
			var cookies = new HttpCookieCollection {
			       		new HttpCookie("fbs_121091137913619", "\"access_token=121091137913619|2.a04r8V6C0WQE1CGkVuxNTw__.3600.1273809600-1834825588|cMdI_lQNBYXLKpw76wjARD9y9sM.&expires=1273809600&secret=yuz1uMckuB8QwNNY2plU7A__&session_key=2.a04r8V6C0WQE1CGkVuxNTw__.3600.1273809600-1834825588&sig=91b7cb563453453452b1bdda7bfcc3e129&uid=1834825588\"")
			};

			try
			{
				FBConnectSession session = auth.GetSession(cookies);
				Assert.Fail("auth.GetSession should have thrown an exception.");
			}
			catch (FBConnectAuthenticationException ex)
			{
				if (ex.Reason == ValidationState.InvalidSignature) correctExceptionThrown = true;
			}

			Assert.IsTrue(correctExceptionThrown);
		}


		private static HttpCookieCollection CreateCookiesWithNoFBConnectInfo()
		{
			return new HttpCookieCollection
			       	{
			       		new HttpCookie("dsfgdfgdfgdfgfg", "dfgdfdfgdfg3345"),
			       		new HttpCookie("AnotherRandomCookie", "RandomCookieValue"),
			       		new HttpCookie(appId + "SuffixWithNoUnderscore", "this should be ignored")
			       	};
		}
	}
}
